import { readFileSync, readdirSync } from "fs";

// 定义全局变量 idPerfix，用于存储符号 ID 的前缀
let idPerfix = "";

// 定义一系列正则表达式用于处理 SVG 内容
const svgTitle = /<svg([^>+].*?)>/;
const clearHeightWidth = /(width|height)="([^>+].*?)"/g;
const hasViewBox = /(viewBox="[^>+].*?")/g;
const clearReturn = /(\r)|(\n)/g;

/**
 * 递归查找并处理指定目录中的所有 SVG 文件
 * @param {string} dir - 目标目录路径
 * @returns {string[]} - 处理后的 SVG 文件内容数组
 */
function findSvgFile(dir) {
  const svgRes = [];

  // 读取目录内容，并获取目录项（文件或文件夹）
  const dirents = readdirSync(dir, { withFileTypes: true });

  for (const dirent of dirents) {
    if (dirent.isDirectory()) {
      // 如果是目录，则递归查找该目录下的 SVG 文件
      svgRes.push(...findSvgFile(dir + dirent.name + "/"));
    } else {
      // 如果是文件，则读取文件内容并进行处理
      const svg = readFileSync(dir + dirent.name)
        .toString()
        .replace(clearReturn, "") // 去除换行符和回车符
        .replace(svgTitle, ($1, $2) => {
          let width = 0;
          let height = 0;

          // 去除 SVG 标签中的宽度和高度属性，并获取它们的值
          let content = $2.replace(clearHeightWidth, (s1, s2, s3) => {
            if (s2 === "width") {
              width = s3;
            } else if (s2 === "height") {
              height = s3;
            }
            return "";
          });

          // 如果没有 viewBox 属性，则添加 viewBox 属性
          if (!hasViewBox.test($2)) {
            content += `viewBox="0 0 ${width} ${height}"`;
          }

          // 将 SVG 标签转换为 symbol 标签，并添加符号 ID
          return `<symbol id="${idPerfix}-${dirent.name.replace(".svg", "")}" ${content}>`;
        })
        .replace("</svg>", "</symbol>"); // 将 </svg> 替换为 </symbol>

      svgRes.push(svg); // 将处理后的 SVG 内容存入数组
    }
  }
  return svgRes; // 返回处理后的 SVG 文件内容数组
}

/**
 * 创建一个 Vite 插件，用于将处理后的 SVG 符号集嵌入到 HTML 文件中
 * @param {string} path - SVG 文件所在的路径
 * @param {string} [perfix='icon'] - 符号 ID 的前缀
 * @returns {Object} - Vite 插件对象
 */
export const svgBuilder = (path, perfix = "icon") => {
  if (path === "") return; // 如果路径为空，则直接返回

  idPerfix = perfix; // 设置符号 ID 的前缀
  const res = findSvgFile(path); // 获取处理后的 SVG 文件数组

  return {
    name: "svg-transform", // 插件名称
    transformIndexHtml(html) {
      // 将生成的 SVG 符号集嵌入到 HTML 文件的 <body> 标签内
      return html.replace(
        "<body>",
        `
          <body>
            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
              ${res.join("")}
            </svg>
        `
      );
    },
  };
};
